<script lang="ts" context="module">
  import type {PopupDirection, ShowMode} from "./conf"
  import ClickOutsideWrapper from '@component/ClickOutsideWrapper.svelte';
</script>
<script lang="ts">
  import { onMount } from 'svelte';
  export let direction: PopupDirection = "lt";
  export let showMode: ShowMode = "hover";

  export let left = 0;
  export let top = 0;
  export let right = 0;
  export let bottom = 0;
  export let oPos = null;
  let toggled = false;

  let elWrapper: HTMLElement;
  let elButton: HTMLButtonElement;
  let pos: DOMRect;

  onMount(() => {
    resize();
    if (isHoverable) {
      pos = oPos
    }
  })


  export const resize = () => {
    pos = elButton.getBoundingClientRect();
  }

  $: needLeft = direction.includes("l");
  $: needTop = direction.includes("t");
  $: needRight = direction.includes("r");
  $: needBottom = direction.includes("b");
  $: isHoverable = showMode === "hover";

  let xleft = 0;
  let xtop = 0;
  let xright = 0;
  let xbottom =0;

  $: {
    switch (direction) {
      case "lt":
        xleft = pos?.left + left;
        xtop = pos?.top + pos?.height + top;
        break;
      case "lb":
        xleft = pos?.left + left;
        xbottom = pos?.bottom - pos?.height - bottom;
        break;
      case "rt":
        xright = pos?.width + right;
        xtop = pos?.top + top;
        break;
      case "rb":
        xright = pos?.right + right;
        xbottom = pos?.bottom - pos?.height - bottom;
        break;
    }
  }

  function initWrapper (el: HTMLElement, mode: ShowMode) {
    if (mode === "hover") {
      el.addEventListener('mouseover', showDropdown);
    }
		return {
			destroy() {
				// the node has been removed from the DOM
        if (mode === "hover") {
				  el.removeEventListener('mouseover', showDropdown);
        }
			}
		}
  }

  function onMouseOver (e) {
    // xleft = e.target.clientX;
    // xtop = e.target.clientY;
    // console.log(xleft, xtop)
    let parent = e.target;
    while (parent) {
      if (elWrapper === parent) {
        
        pos = parent.getBoundingClientRect();
        // console.log('onMouseOver:', e.target.getBoundingClientRect())
        showDropdown();
      }
      parent = parent.parentNode;
    }
  }

  function initDropdownContent (el: HTMLElement, mode: ShowMode) {
    if (mode === "hover") {
      el.addEventListener('mouseout', closeDropdown);
    }
		return {
			destroy() {
				// the node has been removed from the DOM
        if (mode === "hover") {
				  el.removeEventListener('mouseout', closeDropdown);
        }
			}
		}
  }

  function toggleDropdown () {
    toggled = !toggled;
  }
  export const closeDropdown = () => {
    toggled = false;
  }
  export const showDropdown = () => {
    toggled = true;
  }
</script>

<ClickOutsideWrapper on:clickoutside={closeDropdown} exclude={[elWrapper]}>
  <!-- svelte-ignore a11y-mouse-events-have-key-events -->
  <div class="flex-container flex-row" bind:this={elWrapper} use:initWrapper={showMode}>
    <div class="relative inline-block">
      <!-- Dropdown toggle button -->
      <button bind:this={elButton} class="dd-button whitespace-nowrap" on:click={toggleDropdown}>
        <div class="flex-auto pl-2" ><slot name="button-content"></slot></div>
      </button>
      <!-- Dropdown menu -->
      <!-- svelte-ignore a11y-click-events-have-key-events -->
      <div on:click={closeDropdown} class="dd-content" class:hidden={!toggled}
        style:left={needLeft ? `${xleft}px` : null} 
        style:right={needRight ? `${xright}px` : null} 
        style:top={needTop ? `${xtop}px` : null} 
        style:bottom={needBottom ? `${xbottom}px` : null}
        use:initDropdownContent={showMode}
      >
         <slot></slot>
      </div>
    </div>
  </div>
</ClickOutsideWrapper>
<style lang="postcss">
  .dd-button {
    @apply z-10 flex flex-row justify-center items-center;
    width: calc(var(--dd-width) * 1px);
    height: calc(var(--dd-height) * 1px);
  }
  .dd-content {
    @apply fixed z-20 w-56 py-2 mt-2 overflow-hidden rounded-md shadow-xl bg-gray-800;
    width: calc(var(--dd-content-width) * 1px);
  }
  :global(.ddp-item) {
    @apply flex items-center p-3 text-sm capitalize transition-colors duration-200 transform text-gray-300 overflow-hidden cursor-pointer;
  }
  :global(.ddp-item:hover) {
    @apply bg-gray-700 text-white;
  }
</style>